package com.example.ssoapp1.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * AuthFilter
 *
 * @author majun
 * @description AuthFilter
 * @date 2021/9/7
 */
@WebFilter(urlPatterns = { "/home", "/" })
public class SSOFilter implements Filter {


    @Resource
    private RestTemplate restTemplate;

    @Resource
    private ObjectMapper objectMapper;

    @Value("${app.domain}")
    private String domain;

    @Value("${server.port}")
    private String port;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        HttpSession session = req.getSession();
        Object user = session.getAttribute("user");
        if (user != null) {
            filterChain.doFilter(request, response);
            return;
        }

        String ticket = request.getParameter("ticket");
        if (StringUtils.hasLength(ticket)) {
            String token = verify(ticket, req.getSession().getId());

            if (!StringUtils.hasLength(token)) {
                printErr(res, "ticket已经过期或者不存在");
                return;
            }

            String usernameByToken = getUsernameByToken(token);
            session.setAttribute("user", usernameByToken);
        }

        filterChain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }


    private void printErr(HttpServletResponse response, String msg) {
        try {
            response.setContentType("application/json;charset=utf8");
            PrintWriter writer = response.getWriter();
            writer.write(msg);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private String verify(String ticket, String sessionId) {
        String url = "https://localhost:9002/yongdaweb/sso/api/verify?ticket="
                + ticket + "&sessionid=" + sessionId
                + "&logoutUrl=http://www." + domain + ".com:" + port + "/logout";
        System.out.println(url);

        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> entity = new HttpEntity<>(requestHeaders);
        ResponseEntity<String> res = restTemplate.exchange(url, HttpMethod.GET, entity , String.class);

        System.out.println(res.getBody());
        try {
            JsonNode jsonNode = objectMapper.readTree(res.getBody());
            int status = jsonNode.get("errcode").asInt();
            if (status == 200) {
                return jsonNode.get("token").asText();
            }

        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return null;
    }

    private String getUsernameByToken(String token)  {
        String url = "http://localhost:7075/ssoApi/auth/getUserInfo?token=" + token;
        String res = restTemplate.getForObject(url, String.class);
        try {
            JsonNode jsonNode = objectMapper.readTree(res);
            int status = jsonNode.get("status").asInt();
            if (status == 200) {
                return jsonNode.get("data").get("fullname").asText();
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return null;
    }
}
